package com.laoli.lab37;

import java.util.concurrent.CompletableFuture;

/**
 * CompletableFuture示例6-thenCompose()的使用
 */
public class CompletableFutureDemo06 {
    // 任务A的方法
    private static CompletableFuture<String> methodA() {
        return CompletableFuture.supplyAsync(() -> "2");
    }

    // 任务B的方法(依赖任务A的结果)
    private static CompletableFuture<Integer> methodB(String value) {
        return CompletableFuture.supplyAsync(() -> Integer.parseInt(value));
    }

    // 任务C的方法(依赖任务B的结果)
    private static CompletableFuture<Integer> methodC(Integer value) {
        return CompletableFuture.supplyAsync(() -> value * 10);
    }

    public static void main(String[] args) throws InterruptedException {
        // 任务A实现返回字符串"2"
        // 任务B基于任务A的结果，转换为数字2
        // 任务C基于任务B的结果，计算 2*10 的结果
        // 关键点：任务A、B、C都是异步任务,但它们之间有依赖关系；

        // methodC( methodB( methodA() ) )

        // thenApply()方式，出现了回调地狱！！
        /*methodA()
                .thenApply(aResult->{//这个aResult就是任务A的结果，也就是2
                    return methodB(aResult);
                }).thenApply(bFuture->{//这个bFuture是一个CompletableFuture
                    return bFuture.thenApply(bResult->{
                        return methodC(bResult);
                    }).thenApply(cFuture->{//这个cFuture是一个CompletableFuture
                        return cFuture.thenApply(cResult->{
                            return cResult;
                        }).thenAccept(result->{
                            System.out.println("result = " + result);
                        });
                    });
                });*/

        // thenCompose方式，推荐使用！
        methodA()
                .thenCompose(aResult -> methodB(aResult))  // 将A的结果传给B
                .thenCompose(bResult -> methodC(bResult)) // 将B的结果传给C
                .thenAccept(cResult -> System.out.println("cResult = " + cResult)); // 输出C的结果

        // 主线程休眠
        Thread.sleep(100);//之前讲过，CompletableFuture的异步任务默认在ForkJoinPool的守护线程中执行，那如果主线程什么任务都没有，守护线程也就不会执行了，所以这里需要主线程休眠来保持主线程运行。

    }
}

